package cn.zdsoft.configuration.core;

import cn.zdsoft.configuration.core.api.CallbackAble;
import cn.zdsoft.configuration.core.exceptions.ConfigurationException;
import cn.zdsoft.configuration.core.api.IConfigClient;
import cn.zdsoft.configuration.core.client.ZookeeperClient;
import cn.zdsoft.configuration.core.listener.ZKListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * 抽象初始化环境
 *
 * Created by wangdongdong on 2018/5/14.
 */
public abstract class ConfigInitializer implements LifeCycle {

    private static final Logger logger = LoggerFactory.getLogger(ConfigInitializer.class);
    protected IConfigClient configClient;

    public abstract ZKListener getListener();

    public abstract CallbackAble getCallbackAble();

    @Override
    public void start(ConfigContext context) {
        try {
            // 读取配置文件
            Properties globalProperties = mergeProperties();
            // 初始化客户端
            initConfigClient(context, globalProperties);
            // zookeeper 配置
            Properties remoteProperties = configClient.getConfig();
            // 合并配置
            globalProperties.putAll(remoteProperties);
            context.setAttribute(Constants.CONFIG_CONTEXT_PROPERTIES, globalProperties);
        } catch (ConfigurationException e) {
            logger.error("config envioronment initialization error");
            throw new IllegalStateException(e);
        }

    }

    protected void initConfigClient(ConfigContext configContext, Properties properties) throws ConfigurationException {
        this.configClient = new ZookeeperClient();
        configClient.registListener(getListener());
        // 初始化回调参数
        getCallbackAble().init(configContext, properties);
        configClient.registCallAble(getCallbackAble());
        configClient.init(properties);
        configContext.setConfigClient(configClient);
    }

    /**
     * 合并配置信息
     * @return
     * @throws ConfigurationException
     */
    protected Properties mergeProperties() throws ConfigurationException {

        Properties props = new Properties();
        InputStream is = this.getClass().getResourceAsStream(Constants.CONFIG_FILE);

        if (is == null) {
            throw ConfigurationException.createExceptin("'config.properties' file not found !");
        }
        try {
            props.load(is);
            is.close();
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
        // 合并系统属性
        props.putAll(System.getProperties());
        return props;
    }
}
